﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace db
{
    /// <summary>
    /// 我方后手的类
    /// </summary>
    public class Chesser2
    {
        static readonly int line_side_num = 5;//每行的边数



        static readonly int all_sides_num = 2*(line_side_num)*(line_side_num+1);
        static readonly int all_boxes_num = line_side_num * line_side_num;
        static int s_threshold = 5;//全搜索阀值
        bool init_links_tag = false;//初始化链组标记
        bool sym_tag = true;//对称下标记
        //static int init_links_threshold = 3;//初始化链组阀值
        //格：0,1,2,...,24
        //横边：0,1,2,....,29
        //竖边：30,31,...,59
        //int[,] box_side = new int[5, 5];//各个格的边数情况。
        //int[,] box_sideinfo = new int[5, 5];//各个格的边情况，四位二进制1111分别表示左、上、右、下,1表示有边，0表示无边。(边的次序严格按照下棋的次序)
        //int[,] box_linkinfo = new int[5, 5];//各个格链状态表，每个格一个数值，数值的二进制数后两位表示所属链类别（0无链，1非定链，2固定链，3活动链），高位表示其所在链在链类别中的位置
        Dictionary<int, int> box_sides_num;//各个格的边数情况（需更新）
        Dictionary<int,List<int>> side_asociate_boxes;//边和格的相关字典,边号，格号列表，列表容量为1或者2
        Dictionary<int, List<int>> box_asociate_sides;//格和边的相关全字典,格号，边号列表，列表容量4,即4条边
        Dictionary<int, List<int>> box_asociate_sides_e;//格和有效边的相关字典,格号，边号列表，列表容量0-4（需更新）
        Dictionary<int, int> box_state_link;//格的链状态,给定一个格，2进制低2位表示其所属类型，高位表示其所属链编号（复杂需更新）

        //Dictionary<int, int> boxes_type;//格的类型字典
        //Dictionary<int, List<int>> box_adjoin_boxes;//格的相邻格字典

        List<int> sides_you;//对方下的边列表
        List<int> sides_me;//我方要下的边


        List<int> invalid_sides;//失效边，既已经下的边()
        int side_cur_y;//当前对方下的最后一边
        //int side_cur_m;//当前我方的边
        //List<int> complete_link_box_you;//对方构成的完链其中一个格
        List<int> v_single_sides;//所有的单边
        List<int> v_double_sides;//所有的双边
        List<int> v_single_sides_e;//可走的单边(简单更新)
        List<int> v_double_sides_e;//可走的双边(简单更新)
        //List<int> v_single_sides_d;//不可走的单边
        //List<int> v_double_sides_d;//不可走的双边
        List<int> complete_link_sides_me;//我方完全链中的边，每次下封格后更新,我方构成的完链
       // List<int> complete_link_sides_you;//完链中的边，对方构成的完链边
        List<int> complete_link_boxes_you;//对方构成的完链
        //List<int> complete_link_box;//完全链中的格，每次下封格后更新
        List<int> prior_sides;//优先边，即不会为对方构成完链(需更新)
        List<int> prior_single_sides;//
        List<int> prior_double_sides;//
        List<int> low_prior_sides;//次优边，即下该边会为对方构成完链(需更新)
        Dictionary<int,List<int>> low_prior_sides_solid;//次优边中的固定链组，即下其中任意一边，都可构成格，并且可控制优先手
        Dictionary<int, List<int>> low_prior_sides_alive;//次优边中的活动链组，即下其中任意一边，都可构成格，并且不可控制优先手
        Dictionary<int, List<int>> low_prior_sides_unpick;//次优边中非定链组，可以成为固定链，也可成为活链的组


        List<int> div_link_sides;//将格分开的边，通常是四圈格的最后一条边,5.13日修改，未使用

        public Chesser2()//构造函数
        {
            Init();
        }
        public void Init()//初始化系统
        {
            box_sides_num = new Dictionary<int,int>();//各个格的边数情况
            side_asociate_boxes = new Dictionary<int,List<int>>();//边和格的相关字典,边号，格号列表，列表容量为1或者2
            box_asociate_sides = new Dictionary<int,List<int>>();//格和边的相关全字典,格号，边号列表，列表容量4,即4条边
            box_asociate_sides_e = new Dictionary<int,List<int>>();//格和有效边的相关字典,格号，边号列表，列表容量0-4
            box_state_link = new Dictionary<int, int>();

            //boxes_type = new Dictionary<int,int>();//格的类型字典
            //box_adjoin_boxes = new Dictionary<int,List<int>>();//格的相邻格字典

            sides_you = new List<int>();//对方下的边列表
            sides_me = new List<int>();//我方要下的边列表

            invalid_sides = new List<int>();//失效边，既已经下的边

            v_single_sides = new List<int>();//所有的单边
            v_double_sides = new List<int>();//所有的双边
            v_single_sides_e = new List<int>();//可走的单边
            v_double_sides_e = new List<int>();//可走的双边
            complete_link_sides_me = new List<int>();//完全链中的边，每次下封格后更新,我方构成的完链
            complete_link_boxes_you = new List<int>();//对方构成的完链,可能有0-2个
            prior_sides = new List<int>();//优先边，即不会为对方构成完链
            prior_single_sides = new List<int>();
            prior_double_sides = new List<int>();
            low_prior_sides = new List<int>();//次优边，即下该边会为对方构成完链
            low_prior_sides_solid = new Dictionary<int,List<int>>();//次优边中的固定链组，即下其中任意一边，都可构成格，并且可控制优先手
            low_prior_sides_alive = new Dictionary<int, List<int>>();//次优边中的活动链组，即下其中任意一边，都可构成格，并且不可控制优先手
            low_prior_sides_unpick = new Dictionary<int, List<int>>();//次优边中非定链组，可以成为固定链，也可成为活链的组
            for(int i=0;i<all_boxes_num;i++)
            {
                box_sides_num.Add(i,0);
                List<int> sides = new List<int>();//该格对应的四个边
                sides.Add(i);
                sides.Add(i+line_side_num);
                sides.Add(line_side_num * (line_side_num + 1) + line_side_num * (i % line_side_num) + i / line_side_num);
                sides.Add(line_side_num * (line_side_num + 1) + line_side_num * (i % line_side_num) + i / line_side_num + line_side_num);
                box_asociate_sides.Add(i, sides.ToList());
                box_asociate_sides_e.Add(i, sides.ToList());
                //初始化边到格的字典
                //for(int j=0;j<4;j++)
                //{
                //    if(side_asociate_boxes.ContainsKey(sides[j]))
                //    {
                //        side_asociate_boxes[sides[j]].Add(i);
                //    }
                //    else
                //    {
                //        side_asociate_boxes.Add(sides[j], new List<int>(new int[] { i }));
                //    }
                //}
                foreach(int side in sides)
                {
                    if(side_asociate_boxes.ContainsKey(side))
                    {
                        side_asociate_boxes[side].Add(i);
                    }
                    else
                    {
                        side_asociate_boxes.Add(side, new List<int>(new int[] { i }));
                    }
                }
                //boxes_type.Add(i, 0);//初始化类型为0，表示不是链的格
                box_state_link.Add(i,0);//每个格的链的状态
            }
            //初始化单边
            //v_single_sides.AddRange(new int[]{0,1,2,3,4,25,26,27,28,29,30,31,32,33,34,55,56,57,58,59});
            for (int i = 0; i < line_side_num;i++ )
            {
                v_single_sides.Add(i);
            }
            for (int i = line_side_num * line_side_num; i < line_side_num * (line_side_num + 2);i++ )
            {
                v_single_sides.Add(i);
            }
            for (int i = all_sides_num - line_side_num; i < all_sides_num; i++)
            {
                v_single_sides.Add(i);
            }
            //初始化双边
            for (int i = 0; i < all_sides_num; i++)
            {
                if (!v_single_sides.Contains(i))
                    v_double_sides.Add(i);
            }    
            v_single_sides_e.AddRange(v_single_sides.ToList());
            v_double_sides_e.AddRange(v_double_sides.ToList());
            //初始化优先边
            prior_sides.AddRange(v_single_sides.ToList());
            prior_sides.AddRange(v_double_sides.ToList());
            prior_single_sides.AddRange(v_single_sides.ToList());
            prior_double_sides.AddRange(v_double_sides.ToList());


            div_link_sides = new List<int>();

        }
	    public int Put_y(int[] side_nums)//对方下棋，给出边的编号,返回0表示正常，1表示存在错误。
        {
            //检测边的有效性
            foreach(int side in side_nums)
            {
                if (invalid_sides.Contains(side))
                    return 1;
            }


            sides_you.Clear();
            sides_you.AddRange(side_nums);//将对方下的边添加到对方下的边列表中
            side_cur_y = sides_you[sides_you.Count - 1];//对方最后下的边

            

            UpdateState_You(sides_you);

            //更新对方构成的完链
            complete_link_boxes_you.Clear();
            complete_link_boxes_you.AddRange(GetCmpleteLinkByYou());
            //更新对方构成的完链的状态(未做)



            //检测对方是否下了中间格的边，并且中间格的边未下，进入非对称模式,并且不对称下
            //if(!init_links_tag && box_sides_num[all_boxes_num/2] == 1)
            //{
            //    foreach(int side in sides_you)
            //    {
            //        if(box_asociate_sides[all_boxes_num/2].Contains(side))
            //        {
            //            if (invalid_sides.Contains(side - 1) || invalid_sides.Contains(side + 1))
            //            {

            //            }
            //            else
            //            {
            //                sym_tag = false;
            //                break;
            //            }
            //        }
            //    }
                
            //}
            
            return 0;
        }
        /// <summary>
        /// 获取对方构成的完链
        /// </summary>
        /// <returns></returns>
        List<int> GetCmpleteLinkByYou()
        {
            List<int> clink = new List<int>();
            List<int> side_boxes = side_asociate_boxes[side_cur_y];
            List<List<int>> clinks = new List<List<int>>();
            foreach(int box in side_boxes)
            {
                if(box_sides_num[box]==3)
                {
                    clinks.Add(SearchCompleteLinkByBox(box));
                }
            }
            if(clinks.Count == 1 || (clinks.Count>1 && clinks[0].Count == clinks[1].Count && clinks[0].Contains(clinks[1][0])))
            {
                clink.AddRange(clinks[0]);
            }
            else if(clinks.Count == 2)
            {
                if(clinks[0].Count > clinks[1].Count)
                {
                    clink.AddRange(clinks[1]);
                    clink.AddRange(clinks[0]);
                }
                else
                {
                    clink.AddRange(clinks[0]);
                    clink.AddRange(clinks[1]);
                }
            }
            return clink.Distinct().ToList();
        }
        /// <summary>
        /// 更新对方下的边所引发的棋局状态变化
        /// </summary>
        /// <param name="sides">边数组</param>
        /// <param name="n"></param>
        private void UpdateState_You(List<int> sides)//对手下棋，更新状态，参数：边数组，数组大小。(边的次序严格按照下棋的次序)
        {
            if (prior_sides.Count > s_threshold)
            {//简单策略
                UpdateStateBySides(sides.ToList());
            }
            else
            {//复杂策略
                
                UpdateStateAllBySides(sides);
            }
            #region old


            //if (n > 1)
            //{//下的是完链
            //    if (n != complete_link_sides.Count+1)
            //    {//当前完全链未下完
            //        for(int i=0;i<n;i++)
            //        {//更新完全链,一般情况下就剩一个边，如果不是，我操，对手很菜啊！
            //            complete_link_sides.Remove(sides[i]);
            //        }

            //    }
            //    UpdateStateBySides(sides);//对手下的棋更新棋局
            //}
            //else
            //{//下的是单边
            //    List<int> t_box = side_asociate_boxes[sides[0]];//与该边相关的格列表
            //    for (int i = 0; i < t_box.Count;i++ )
            //    {
            //        //更新格边的情况
            //        box_sides_num[t_box[i]] = box_sides_num[t_box[i]] + 1;
            //        //更新格有效边的情况
            //        box_asociate_sides_e[t_box[i]].Remove(sides[0]);
            //    }
            //    //更新链状态,对每个受影响的格进行检索
            //    complete_link_box_you.Clear();//清除对方构成的完链
            //    for(int i=0;i<t_box.Count;i++)
            //    {
            //        List<int> box_link = SearchLink(t_box[i],sides[0]);//从该格开始搜索链，并更新
            //        if (box_link.Count > 1)
            //        {//是链
            //            complete_link_box_you.Add(t_box[i]);//添加对方构成的完链的起始格
            //        }
            //        //else
            //        //{//不是链
            //        //    UpdateStateBySide(sides[0]);
            //        //}

            //    }
            //    UpdateStateBySide(sides[0]);//以该单边更新棋局(只更新边和格的状态)
            //}
            #endregion
        }
       
	    public int[] Get_m()//获取本方下棋，返回边的编号集合。
        {
            sides_me.Clear();//清空本方当前下边
            //清除我方否成的完链边中对方已经下的边
            if(complete_link_sides_me.Contains(side_cur_y))//对方做出了让步，我操，厉害啊
            {
                complete_link_boxes_you.Clear();
            }
            foreach(int side in sides_you)
            {
                if (complete_link_sides_me.Contains(side))
                    complete_link_sides_me.Remove(side);
            }
            if (!init_links_tag && prior_sides.Count > s_threshold)
            {//简单策略
                SimpleSrategy(sides_you);
            }
            else
            {//复杂策略
                InitLinks();
                ComplexStrategy(sides_you);
            }
            complete_link_sides_me = complete_link_sides_me.Distinct().ToList();


            return sides_me.Distinct().ToArray();
        }
        
        void SimpleSrategy(List<int> sides)//简单下棋策略，前期
        {//下对方下的边的对称边
            sides_me.Clear();
            sides_me.AddRange(complete_link_sides_me) ;
            complete_link_sides_me.Clear();
            sides_me.AddRange(LinkToSides(complete_link_boxes_you));//SearchLinkBySide(side_cur_y).AsEnumerable());//添加对方构成完链边，如果有
            //sides_me.Add(prior_sides[0]);//添加优先边
            bool t_add_tag = false;//添加最后下的一边标记
            //对称下棋策略，我方后手的情况
            int sym_side = GetSymSide(side_cur_y);
            Random rd = new Random();
            if(prior_sides.Count == 0)
            {//无优先边了，进入复杂策略模式
                t_add_tag = true;
                init_links_tag = true;
                InitLinks();
                ComplexStrategy(sides_you);
            }
            else
            {
                if(prior_sides.Contains(sym_side) && sym_tag)
                {
                    sides_me.Add(sym_side);
                    t_add_tag = true;
                }
                else
                {
                    if (v_single_sides.Contains(side_cur_y))
                    {//如果对方下的是单边,我方优先从单边中选取
                        if (prior_single_sides.Count > 0)
                        {
                            sides_me.Add(prior_single_sides[rd.Next(prior_single_sides.Count)]);
                            t_add_tag = true;
                        }
                    }
                    else if (v_double_sides.Contains(side_cur_y))
                    {//如果对方下的是双边,我方优先从双边中选取
                        if (prior_double_sides.Count > 0)
                        {
                            sides_me.Add(prior_double_sides[rd.Next(prior_double_sides.Count)]);
                            t_add_tag = true;
                        }
                    }
                }
            }
            if (!t_add_tag)
            {//没有有效策略边，从优先边中选一个
                sides_me.Add(GetRandomSide());
                init_links_tag = true;
                //不是对称边了或既定策略了，进入复杂策略
            }
            UpdateStateBySides(sides_me);
        }
        void ComplexStrategy(List<int> sides)//复杂下棋策略，后期
        {
            sides_me.Clear();
            sides_me.AddRange(complete_link_sides_me);//先简单的把我方构成的完链，对方没下完的放到我方要下的集合中
            complete_link_sides_me.Clear();

            bool last_tag = false;
            int clink_type = GetCompleteLinkType(complete_link_boxes_you);
            if(clink_type == 0)
            {//0表示对方没有构成完链

            }
            else if (clink_type == 2 || isEnd())//5.15日修改，是结束的话全占
            {//2表示固定完链
                sides_me.AddRange(LinkToSides(complete_link_boxes_you));
            }
            else
            {
                if (EvalSituation(prior_sides.Count, low_prior_sides_unpick.Count, low_prior_sides_solid.Count))
                {//当前局势优势，我方占据完链
                    sides_me.AddRange(LinkToSides(complete_link_boxes_you));
                }
                else
                {//当前局势劣,做出让步
                    sides_me.AddRange(LinkToSidesConcession(complete_link_boxes_you));
                    complete_link_sides_me.AddRange(LinkToSidesConcessionSide(complete_link_boxes_you));
                    last_tag = true;
                }
            }
            #region old
            
         
            //sides_me.AddRange(GetSolideCompleteSidesByLinks(complete_link_boxes_you));
            //List<List<int>> indef_links = GetIndefCompleteLinksByLinks();
            //if(indef_links.Count == 2)
            //{

            //}
            //if(complete_link_boxes_you.Count == 1)
            //{//对方构成了1个完全链
                
            //    int clink_type = GetCompleteLinkType(complete_link_boxes_you);
            //    if(clink_type == 2)
            //    {//2表示固定完链
            //        sides_me.AddRange(LinkToSides(complete_link_boxes_you));
            //    }
            //    else
            //    {
            //        if (EvalSituation(prior_sides.Count, low_prior_sides_unpick.Count, low_prior_sides_solid.Count))
            //        {//当前局势优
            //            sides_me.AddRange(LinkToSides(complete_link_boxes_you));
            //        }
            //        else
            //        {//当前局势劣
            //            sides_me.AddRange(LinkToSidesConcession(complete_link_boxes_you));
            //            complete_link_sides_me.AddRange(LinkToSidesConcessionSide(complete_link_boxes_you));
            //        }
            //    }
            //}
            //else if (complete_link_boxes_you.Count == 2)
            //{
            //    int link1_type = GetCompleteLinkType(complete_link_boxes_you[0]);
            //    int link2_type = GetCompleteLinkType(complete_link_boxes_you[1]);
            //    if (link1_type == 2)
            //    {//第一个链是固定完链
            //        sides_me.AddRange(LinkToSides(complete_link_boxes_you[0]));
            //        if (link2_type == 2)
            //        {//第二个链是固定完链
            //            sides_me.AddRange(LinkToSides(complete_link_boxes_you[1]));
            //        }
            //        else
            //        {
            //            if (EvalSituation(prior_sides.Count, low_prior_sides_unpick.Count, low_prior_sides_solid.Count))
            //            {//当前局势优
            //                sides_me.AddRange(LinkToSides(complete_link_boxes_you[1]));
            //            }
            //            else
            //            {//当前局势劣
            //                sides_me.AddRange(LinkToSidesConcession(complete_link_boxes_you[1]));
            //                complete_link_sides_me.AddRange(LinkToSidesConcessionSide(complete_link_boxes_you[1]));
            //            }
            //        }
            //    }
            //    else
            //    {//第一个链是非固定完链

            //        sides_me.AddRange(LinkToSides(complete_link_boxes_you[1]));
            //        if (EvalSituation(prior_sides.Count, low_prior_sides_unpick.Count, low_prior_sides_solid.Count))
            //        {//当前局势优
            //            sides_me.AddRange(LinkToSides(complete_link_boxes_you[0]));
            //        }
            //        else
            //        {//当前局势劣
            //            sides_me.AddRange(LinkToSidesConcession(complete_link_boxes_you[0]));
            //            complete_link_sides_me.AddRange(LinkToSidesConcessionSide(complete_link_boxes_you[0]));
            //        }
            //    }
            //}
            #endregion
            if (!last_tag && !isEnd())
            {//没有让步，需要给出最后下的一条边
                UpdateStateAllBySides(sides_me);//在这里还要重新计算链表
                List<int> lcs = new List<int>();
                lcs.Add(GetLastComplexSide());
                sides_me.Add(lcs[0]);
                UpdateStateAllBySides(lcs);
            }
            else if(sides_me.Count == 0)
            {//还没有链的前阶段，给出一条边
                sides_me.Add(GetLastComplexSide());
                UpdateStateAllBySides(sides_me);
            }
            else
            {
                UpdateStateAllBySides(sides_me);//每条边保证只更新一次
            }
            
        }
        bool isEnd()
        {
            bool end = false;
            if (low_prior_sides_alive.Count == 0 && low_prior_sides_solid.Count == 0 && low_prior_sides_unpick.Count == 0)
            {
                end = true;
            }
            return end;
        }
        /// <summary>
        /// 初始化各个链组
        /// </summary>
        void InitLinks()
        {
            div_link_sides.Clear();//清除分格优先边
            low_prior_sides_alive.Clear();
            low_prior_sides_solid.Clear();
            low_prior_sides_unpick.Clear();
            List<int> checked_boxes = new List<int>();
            //int[] t_box_tag = new int[30]{ 0 };
            //对每一个格进行搜索,对不是链的格进行分析
            for(int i=0;i<all_boxes_num;i++)
            {
                //Dictionary<int,int> other_box = new Dictionary<int,int>();//与搜索边相邻的尚未搜索的格,格号，添加边号
                if (!checked_boxes.Contains(i) && box_sides_num[i] == 2)
                {
                    List<int> cur_box_link = SearchLinkByBox(i);
                    foreach(int box in cur_box_link)
                    {
                        checked_boxes.Add(box);
                    }
                    if (IsCompleteLink(cur_box_link) || cur_box_link.Count == 0)
                        continue;
                    int cur_link_type = GetLinkType(cur_box_link);
                    int cur_link_tag = cur_box_link.Min();
                    int cur_box_state_value = cur_link_tag<<2 + cur_link_type;
                    foreach(int box in cur_box_link)
                    {
                        box_state_link[box] = cur_box_state_value;
                    }
                    if(cur_link_type == 1)
                    {//非定链
                        if (low_prior_sides_unpick.ContainsKey(cur_link_tag))
                        {
                            low_prior_sides_unpick.Remove(cur_link_tag);
                        }
                        low_prior_sides_unpick.Add(cur_link_tag, cur_box_link);
                    }
                    else if(cur_link_type == 2)
                    {//固定连
                        if (low_prior_sides_solid.ContainsKey(cur_link_tag))
                        {
                            low_prior_sides_solid.Remove(cur_link_tag);
                        }
                        low_prior_sides_solid.Add(cur_link_tag, cur_box_link);
                    }
                    else if(cur_link_type == 3)
                    {//活动链
                        if (low_prior_sides_alive.ContainsKey(cur_link_tag))
                        {
                            low_prior_sides_alive.Remove(cur_link_tag);
                        }
                        low_prior_sides_alive.Add(cur_link_tag, cur_box_link);
                    }
                }
                checked_boxes.Add(i);

            }
        }
        #region old SearchLinkByBox
        /// <summary>
        /// 给定一个起始格，搜索链或者完链
        /// </summary>
        /// <param name="start_box">起始格</param>
        /// <returns></returns>
        List<int> SearchLinkByBox(int cur_box, int start_box)
        {
            List<int> link = new List<int>();
            if (box_sides_num[cur_box] < 2 || box_sides_num[cur_box] > 3)//不是链格
                return link;
            else
            {//链的格，把该格加入
                link.Add(cur_box);
            }
            List<int> cur_box_sides = box_asociate_sides_e[cur_box];
            foreach (int side in cur_box_sides)
            {
                List<int> side_boxes = side_asociate_boxes[side];
                foreach (int side_box in side_boxes)
                {
                    if (side_box != start_box && side_box != cur_box)
                    {
                        List<int> new_link = SearchLinkByBox(side_box, start_box);
                        link.AddRange(new_link);//递归添加链中的格
                    }
                }
            }
            return link.Distinct().ToList();
        }
        #endregion
       
        /// <summary>
        /// 给定一个起始格，搜索链或者完链
        /// </summary>
        /// <param name="start_box">起始格</param>
        /// <returns></returns>
        List<int> SearchLinkByBox(int start_box)
        {
            List<int> link = new List<int>();
            List<int> link_sides = new List<int>();//当前链中拟失效边,5.13好修改
            if (box_sides_num[start_box] < 2 || box_sides_num[start_box] > 3)//不是链格
                return link;
            else
            {//链的格，把该格加入
                link.Add(start_box);
                link_sides.AddRange(box_asociate_sides_e[start_box].ToList());//当前链中拟失效边,5.13好修改
            }




            List<int> start_box_sides = box_asociate_sides_e[start_box].ToList();
            foreach (int side in start_box_sides)
            {
                bool s_tag = true;//是否继续向下搜索
                int cur_side = side;
                int cur_box = start_box;
                while(s_tag)
                {
                    s_tag = false;
                    List<int> side_boxes = side_asociate_boxes[cur_side].ToList();
                    foreach(int side_box in side_boxes)
                    {
                        if(side_box != cur_box && !link.Contains(side_box))// && (box_sides_num[side_box] == 2 || box_sides_num[side_box] == 3))
                        {
                            if(box_sides_num[side_box] == 2)
                            {//链，继续向下搜索
                                link.Add(side_box);
                                link_sides.AddRange(box_asociate_sides_e[side_box].ToList());//当前链中拟失效边,5.13好修改
                                s_tag = true;
                                cur_box = side_box;
                                List<int> cur_box_sides = box_asociate_sides_e[cur_box].ToList();
                                cur_box_sides.Remove(cur_side);
                                cur_side = cur_box_sides[0];
                            }
                            else if(box_sides_num[side_box] == 3)
                            {//完链，添加格，不再向下搜索
                                link.Add(side_box);
                            }
                            else if (box_sides_num[side_box] == 1)//当前链中拟失效边,5.13好修改
                            {
                                List<int> side_box_sides = box_asociate_sides_e[side_box].ToList();
                                List<int> side_box_sides_cp = side_box_sides.ToList();
                                foreach (int side_box_side in side_box_sides_cp)
                                {
                                    if (link_sides.Contains(side_box_side))
                                    {
                                        side_box_sides.Remove(side_box_side);
                                    }
                                }
                                if(side_box_sides.Count == 1)
                                {
                                    div_link_sides.Add(side_box_sides[0]);//添加分格的优先边
                                }
                                //if (side_box_sides.Count == 1)
                                //{//是链的格
                                //    link.Add(side_box);
                                //    link_sides.AddRange(side_box_sides.ToList());//当前链中拟失效边,5.13好修改
                                //    if (box_state_link[side_box] == 0)
                                //    {//不是别的链，继续搜索
                                //        s_tag = true;
                                //        cur_box = side_box;
                                //        cur_side = side_box_sides[0];
                                //    }
                                //    else
                                //    {
                                //        //div_link_sides.Add(side_box_sides[0]);//添加到分格的边
                                //    }

                                //}
                            }
                        }
                    }
                }
                //List<int> side_boxes = side_asociate_boxes[side];
                //foreach (int side_box in side_boxes)
                //{
                //    if (side_box != start_box && side_box != cur_box)
                //    {
                //        List<int> new_link = SearchLinkByBox(side_box, start_box);
                //        link.AddRange(new_link);//递归添加链中的格
                //    }
                //}
            }
            return link.Distinct().ToList();
        }
        /// <summary>
        /// 给一个起始格搜索完链,也可以搜索拟完链
        /// </summary>
        /// <param name="start_box"></param>
        /// <returns></returns>
        List<int> SearchCompleteLinkByBox(int start_box)
        {
            List<int> link = new List<int>();
            List<int> link_sides = new List<int>();//当前链中拟失效边,5.13好修改
            if (box_sides_num[start_box] < 2 || box_sides_num[start_box] > 3)//不是链格
                return link;
            else
            {//链的格，把该格加入
                link.Add(start_box);
                link_sides.AddRange(box_asociate_sides_e[start_box].ToList());//当前链中拟失效边,5.13好修改
            }

            List<int> start_box_sides = box_asociate_sides_e[start_box].ToList();
            foreach (int side in start_box_sides)
            {
                bool s_tag = true;//是否继续向下搜索
                int cur_side = side;
                int cur_box = start_box;
                while (s_tag)
                {
                    s_tag = false;
                    List<int> side_boxes = side_asociate_boxes[cur_side].ToList();//已复制，可增删
                    foreach (int side_box in side_boxes)
                    {
                        if (side_box != cur_box && !link.Contains(side_box))// && (box_sides_num[side_box] == 2 || box_sides_num[side_box] == 3))
                        {
                            if (box_sides_num[side_box] == 2)
                            {//链，继续向下搜索
                                link.Add(side_box);
                                link_sides.AddRange(box_asociate_sides_e[side_box].ToList());//当前链中拟失效边,5.13好修改
                                s_tag = true;
                                cur_box = side_box;
                                List<int> cur_box_sides = box_asociate_sides_e[cur_box].ToList();
                                cur_box_sides.Remove(cur_side);
                                cur_side = cur_box_sides[0];
                            }
                            else if (box_sides_num[side_box] == 3)
                            {//完链，添加格，不再向下搜索
                                link.Add(side_box);
                            }
                            else if (box_sides_num[side_box] == 1)//当前链中拟失效边,5.13好修改
                            {
                                List<int> side_box_sides = box_asociate_sides_e[side_box].ToList();
                                List<int> side_box_sides_cp = side_box_sides.ToList();
                                foreach (int side_box_side in side_box_sides_cp)
                                {
                                    if (link_sides.Contains(side_box_side))
                                    {
                                        side_box_sides.Remove(side_box_side);
                                    }
                                }
                                if (side_box_sides.Count == 1)
                                {//是链的格
                                    link.Add(side_box);
                                    link_sides.AddRange(side_box_sides.ToList());//当前链中拟失效边,5.13好修改
                                    s_tag = true;
                                    cur_box = side_box;
                                    cur_side = side_box_sides[0];

                                }
                            }

                        }
                    }
                }

            }
            return link.Distinct().ToList();
        }
        /// <summary>
        /// 判断链是否是完链
        /// </summary>
        /// <param name="boxes">一组链</param>
        /// <returns></returns>
        bool IsCompleteLink(List<int> boxes)
        {
            bool val = false;
            foreach(int box in boxes)
            {
                if(box_sides_num[box] == 3)
                {
                    val = true;
                    break;
                }
            }
            return val;
        }
       
        /// <summary>
        /// 给一组边更新棋局状态，更新边和格的状态
        /// </summary>
        /// <param name="sides">边列表</param>
        void UpdateStateBySides(List<int> sides_list)
        {
            //增加失效边更新验证，防止重复更新边
            sides_list = sides_list.Distinct().ToList();
            List<int> t_sides_list = sides_list.ToList();
            foreach(int side in t_sides_list)
            {
                if (invalid_sides.Contains(side))
                    sides_list.Remove(side);
            }



            foreach(int side in sides_list)
            {
                
                List<int> side_boxes = side_asociate_boxes[side];//与改变相关的格列表
                foreach(int box in side_boxes)
                {
                    box_sides_num[box] = box_sides_num[box] + 1;//更新与该边相关的格变数
                    box_asociate_sides_e[box].Remove(side);//更新格的有效边
                }
                //更新有效单边和双边
                if(v_single_sides_e.Contains(side))
                {
                    v_single_sides_e.Remove(side);
                }
                else
                {
                    v_double_sides_e.Remove(side);
                }
                //将失效边从优先边或次优边中删除
                if(prior_sides.Contains(side))
                {
                    prior_sides.Remove(side);
                }
                else
                {
                    low_prior_sides.Remove(side);
                }
                prior_single_sides.Remove(side);
                prior_double_sides.Remove(side);
            }
            List<int> t_prior_sides = prior_sides.ToList();//创建临时优先边列表，便于下面操作
            //更新优先边
            foreach (int side in t_prior_sides)
            {
                List<int> side_boxes = side_asociate_boxes[side];
                foreach(int box in side_boxes)
                {
                    if(box_sides_num[box] > 1)
                    {//该格是链格,将该边从优先边中删除,加入次优边
                        prior_sides.Remove(side);
                        prior_single_sides.Remove(side);
                        prior_double_sides.Remove(side);
                        low_prior_sides.Add(side);
                    }
                }
            }
            //更新失效边
            invalid_sides.AddRange(sides_you);
            invalid_sides.AddRange(sides_me);
            invalid_sides = invalid_sides.Distinct().ToList();
        }

        /// <summary>
        /// 给一组边更新棋局状态，更新边和格的状态,更新链的状态
        /// </summary>
        /// <param name="sides">边列表</param>
        void UpdateStateAllBySides(List<int> sides)
        {
            UpdateStateBySides(sides);
            //更新链的状态,先简单的初始化把
            InitLinks();
        }
        /// <summary>
        /// 必须有优先边
        /// </summary>
        /// <returns></returns>
        int GetRandomSide()
        {
            bool t_add_tag = false;
            int side = -1;
            int sym_side = GetSymSide(side_cur_y);
            Random rd = new Random();
            if (prior_sides.Count == 0)
            {//无优先边了，进入复杂策略模式
                
            }
            else
            {
                if (prior_sides.Contains(sym_side) && sym_tag)// && (init_links_tag && box_sides_num[all_boxes_num / 2] == 4))//5.15修改条件,电脑后手不使用该条件
                {
                    side = sym_side;
                    t_add_tag = true;
                }
                else
                {
                    if (v_single_sides.Contains(side_cur_y))
                    {//如果对方下的是单边,我方优先从单边中选取
                        if (prior_single_sides.Count > 0)
                        {
                            side = prior_single_sides[rd.Next(prior_single_sides.Count)];
                            t_add_tag = true;
                        }
                    }
                    else if (v_double_sides.Contains(side_cur_y))
                    {//如果对方下的是双边,我方优先从双边中选取
                        if (prior_double_sides.Count > 0)
                        {
                            side = prior_double_sides[rd.Next(prior_double_sides.Count)];
                            t_add_tag = true;
                        }
                    }
                }
            }
            if (!t_add_tag)
            {//没有有效策略边，从优先边中选一个

                side = prior_sides[rd.Next(prior_sides.Count)];
            }
            return side;
        }
        /// <summary>
        /// 获取复杂策略下的最后一条边，在没有妥协的前提下(妥协的话不需要再下)
        /// </summary>
        /// <returns></returns>
        int GetLastComplexSide()
        {
            int side = 0;//要返回的边

            //先验证优先边中有无分格优先边，如有，直接返回一边
            bool div_side_tag = false;
            foreach (int div_side in div_link_sides)
            {
                if (prior_sides.Contains(div_side))
                {
                    div_side_tag = true;
                    side = div_side;
                }
            }
            if (div_side_tag)
                return side;




            int prior_sides_num = prior_sides.Count;
            int unpick = low_prior_sides_unpick.Count;
            int solid = low_prior_sides_solid.Count;


            if (prior_sides_num==0&&solid == 0 && unpick > 1)//继续执行对称边,5.14日修改
            {
                
                int sym_side = GetSymSide(side_cur_y);
                if (low_prior_sides.Contains(sym_side) && sym_tag)
                {
                    side = sym_side;
                    return side;
                }
            }


            if(prior_sides_num > 0)
            {//有优先边
                if((prior_sides_num & 1) == 1)
                {//优先边为奇数个
                    if (unpick > 0 && solid > 0)
                    {
                        if ((unpick & 1) == (solid & 1))
                        {//非定链和固定链奇偶相同
                            side = GetRandomSide();
                        }
                        else
                        {//可以搜索改变优先边的条数，先简单的任意给出个固定链边,需要更新我方构成的完链
                            int link_tag = low_prior_sides_solid.First().Key;
                            for (int i = 0; i < all_boxes_num; i++)
                            {
                                if (box_state_link[i] == link_tag)
                                    box_state_link[i] = -1;//该格已失效，不在搜索链了
                            }
                            List<int> complete_link_sides = LinkToSides(low_prior_sides_solid[link_tag]);//我方构成的完链边
                            side = complete_link_sides[0];
                            complete_link_sides.Remove(side);
                            complete_link_sides_me.AddRange(complete_link_sides);
                        }
                    }
                    //else if (unpick > 0)
                    //{//非固定链非0，固定链为0
                    //    side = prior_sides[0];
                    //}
                    //else if (solid > 0)
                    //{//非固定链0，固定链非0

                    //}
                    else
                    {
                        side = GetRandomSide();
                    }
                }
                else
                {//优先边为偶数个
                    if (unpick > 0 && solid > 0)
                    {
                        if ((unpick & 1) == (solid & 1))
                        {//非定链和固定链奇偶相同
                            int link_tag = low_prior_sides_solid.First().Key;
                            for (int i = 0; i < all_boxes_num; i++)
                            {
                                if (box_state_link[i] == link_tag)
                                    box_state_link[i] = -1;//该格已失效，不在搜索链了
                            }
                            List<int> complete_link_sides = LinkToSides(low_prior_sides_solid[link_tag]);//我方构成的完链
                            side = complete_link_sides[0];
                            complete_link_sides.Remove(side);
                            complete_link_sides_me.AddRange(complete_link_sides);
                        }
                        else
                        {//可以搜索改变优先边的条数，先简单的任意给出个固定链边,需要更新我方构成的完链
                            side = GetRandomSide();
                        }
                    }
                    //else if (unpick > 0)
                    //{//非固定链非0，固定链为0
                    //    side = prior_sides[0];
                    //}
                    //else if (solid > 0)
                    //{//非固定链0，固定链非0

                    //}
                    else
                    {
                        side = GetRandomSide();
                    }
                }
                
            }
            else
            {//无优先边
                if (unpick > 0 && solid > 0)
                {
                    if ((unpick & 1) == (solid & 1))
                    {//非定链和固定链奇偶相同

                        int link_tag = low_prior_sides_solid.First().Key;
                        for (int i = 0; i < all_boxes_num; i++)
                        {
                            if (box_state_link[i] == link_tag)
                                box_state_link[i] = -1;//该格已失效，不在搜索链了
                        }
                        List<int> complete_link_sides = LinkToSides(low_prior_sides_solid[link_tag]);//我方构成的完链
                        side = complete_link_sides[0];
                        complete_link_sides.Remove(side);
                        complete_link_sides_me.AddRange(complete_link_sides);
                    }
                    else
                    {//可以搜索改变优先边的条数，先简单的任意给出个固定链边,需要更新我方构成的完链
                        if((unpick & 1) == 1)
                        {//非定链为奇，固定链为偶
                            int link_tag = low_prior_sides_unpick.First().Key;
                            for (int i = 0; i < all_boxes_num; i++)
                            {
                                if (box_state_link[i] == link_tag)
                                    box_state_link[i] = -1;//该格已失效，不在搜索链了
                            }
                            List<int> complete_link_sides = LinkToSides(low_prior_sides_unpick[link_tag]);//我方构成的完链
                            side = GetFixUnpickSide(low_prior_sides_unpick[link_tag]);
                            complete_link_sides.Remove(side);
                            complete_link_sides_me.AddRange(complete_link_sides);
                        }
                        else
                        {//非定链为偶，固定链为奇
                            //存在固定链格很多，余下都是非定链的情况
                            //if(low_prior_sides_alive.Count == 0 && low_prior_sides_unpick.Count < low_prior_sides_solid)
                            //{

                            //}
                            int link_tag = low_prior_sides_solid.First().Key;
                            for (int i = 0; i < all_boxes_num; i++)
                            {
                                if (box_state_link[i] == link_tag)
                                    box_state_link[i] = -1;//该格已失效，不在搜索链了
                            }
                            List<int> complete_link_sides = LinkToSides(low_prior_sides_solid[link_tag]);//我方构成的完链
                            side = complete_link_sides[0];
                            complete_link_sides.Remove(side);
                            complete_link_sides_me.AddRange(complete_link_sides);
                        }

                    }
                }
                else if (unpick > 0)
                {//非固定链非0，固定链为0
                    int link_tag = low_prior_sides_unpick.First().Key;
                    for (int i = 0; i < all_boxes_num; i++)
                    {
                        if (box_state_link[i] == link_tag)
                            box_state_link[i] = -1;//该格已失效，不在搜索链了
                    }
                    List<int> complete_link_sides = LinkToSides(low_prior_sides_unpick[link_tag]);//我方构成的完链
                    side = GetFixUnpickSide(low_prior_sides_unpick[link_tag]);
                    complete_link_sides.Remove(side);
                    complete_link_sides_me.AddRange(complete_link_sides);
                }
                else if (solid > 0)
                {//非固定链0，固定链非0
                    int link_tag = low_prior_sides_solid.First().Key;
                    for (int i = 0; i < all_boxes_num; i++)
                    {
                        if (box_state_link[i] == link_tag)
                            box_state_link[i] = -1;//该格已失效，不在搜索链了
                    }
                    List<int> complete_link_sides = LinkToSides(low_prior_sides_solid[link_tag]);//我方构成的完链
                    side = complete_link_sides[0];
                    complete_link_sides.Remove(side);
                    complete_link_sides_me.AddRange(complete_link_sides);
                }
                else
                {
                    int link_tag = low_prior_sides_alive.First().Key;
                    for (int i = 0; i < all_boxes_num; i++)
                    {
                        if (box_state_link[i] == link_tag)
                            box_state_link[i] = -1;//该格已失效，不在搜索链了
                    }
                    List<int> complete_link_sides = LinkToSides(low_prior_sides_alive[link_tag]);//我方构成的完链
                    side = complete_link_sides[0];
                    complete_link_sides.Remove(side);
                    complete_link_sides_me.AddRange(complete_link_sides);
                }
            }
            return side;
        }
        /// <summary>
        /// 获取非定链->固定完链的一条边
        /// </summary>
        /// <param name="unpick_link">非定链</param>
        /// <returns></returns>
        int GetFixUnpickSide(List<int> unpick_link)
        {
            int side = -1;
            if (unpick_link.Count == 2)
            {//只有链格数为2时才有可能是非定链
                List<int> sides = LinkToSides(unpick_link);
                sides.Sort();
                if (sides[0] == sides[1] - 1)
                    side = sides[2];
                else if (sides[1] == sides[2] - 1)
                    side = sides[0];
                else
                    side = sides[1];
            }
            return side;
        }
        /// <summary>
        /// 获取妥协的让对方下的边,通常就一条边
        /// </summary>
        /// <param name="boxes">一个非固定链</param>
        /// <returns></returns>
        List<int> LinkToSidesConcessionSide(List<int> boxes)
        {
            List<int> con_sides = LinkToSides(boxes);
            int con_side = con_sides.ElementAt(con_sides.Count - 2);
            if(boxes.Count ==  4 && con_sides.Count == 3)
            {
                con_sides.Remove(con_side);
                
            }
            else if (boxes.Count > 4 && (boxes.Count & 1) == 0 && (boxes.Count == con_sides.Count + 1))
            {
                List<int> do_sides = LinkToSidesConcession(boxes);
                foreach (int side in do_sides)
                {
                    con_sides.Remove(side);
                }
                return con_sides;
            }
            else
            {
                con_sides.Clear();
                con_sides.Add(con_side);
            }
            return con_sides;

        }
        /// <summary>
        /// 获取妥协的要下的边列表
        /// </summary>
        /// <param name="boxes">一个非固定链</param>
        /// <returns></returns>
        List<int> LinkToSidesConcession(List<int> boxes)
        {      
            List<int> con_sides = LinkToSides(boxes);
            int con_side = con_sides.ElementAt(con_sides.Count - 2);
            //5.13日修改
            if (boxes.Count == 4 && con_sides.Count == 3)
            {
                con_sides.Clear();
                con_sides.Add(con_side);
                return con_sides;
            }

            try
            {
                if (boxes.Count > 4 && (boxes.Count & 1) == 0 && (boxes.Count == con_sides.Count + 1))
                {
                    List<int> boxes3 = new List<int>();
                    foreach (int box in boxes)
                    {
                        if (box_sides_num[box] == 3)
                            boxes3.Add(box);
                    }
                    con_sides = SearchLinkByBox(boxes3[0]);
                    List<int> con_sides1 = SearchLinkByBox(boxes3[1]);
                    con_sides.Insert(0, con_sides1[0]);
                    con_sides.RemoveAt(con_sides.Count - 1);
                    con_sides.RemoveAt(con_sides.Count - 2);
                    return con_sides;
                }
            }
            catch { }


            if(low_prior_sides_alive.Count == 0&& low_prior_sides_solid.Count == 0 && low_prior_sides_unpick.Count == 0)
            {

            }
            else
            {
                con_sides.Remove(con_side);
            }
            return con_sides;
        }
        /// <summary>
        /// 评估当前棋局是否对我方有利
        /// </summary>
        /// <param name="prior_sides">优先边数</param>
        /// <param name="undef_link">非定链数</param>
        /// <param name="solid_link">固定链数</param>
        /// <returns></returns>
        bool EvalSituation(int t_prior_sides_num,int undef_link,int solid_link)
        {
            bool isGood = true;
            int prior_sides_num = t_prior_sides_num;
            int unpick = undef_link;
            int solid = solid_link;
            if (prior_sides_num > 0)
            {//有优先边
                if ((prior_sides_num & 1) == 1)
                {//优先边为奇数个
                    if (unpick > 0 && solid > 0)
                    {
                        if ((unpick & 1) == (solid & 1))
                        {//非定链和固定链奇偶相同
                            isGood = true;
                        }
                        else
                        {//可以搜索改变优先边的条数，先简单的任意给出个固定链边,需要更新我方构成的完链
                            isGood = false;
                        }
                    }
                    else if (unpick > 0)
                    {//非固定链非0，固定链为0
                        if((unpick & 1) == 1)
                        {
                            isGood = false;
                        }
                        else
                        {
                            isGood = true;
                        }
                    }
                    else if (solid > 0)
                    {//非固定链0，固定链非0
                        if ((solid & 1) == 1)
                        {
                            isGood = false;
                        }
                        else
                        {
                            isGood = true;
                        }
                    }
                    else
                    {//非定链和固定链都是0
                        isGood = true;
                    }
                }
                else
                {//优先边为偶数个
                    if (unpick > 0 && solid > 0)
                    {
                        if ((unpick & 1) == (solid & 1))
                        {//非定链和固定链奇偶相同
                            isGood = false;
                        }
                        else
                        {//可以搜索改变优先边的条数，先简单的任意给出个固定链边,需要更新我方构成的完链
                            isGood = true;
                        }
                    }
                    else if (unpick > 0)
                    {//非固定链非0，固定链为0
                        if ((unpick & 1) == 1)
                        {
                            isGood = true;
                        }
                        else
                        {
                            isGood = false;
                        }
                    }
                    else if (solid > 0)
                    {//非定链0，固定链非0
                        if ((solid & 1) == 1)
                        {
                            isGood = true;
                        }
                        else
                        {
                            isGood = false;
                        }
                    }
                    else
                    {//非定链和固定链都是0
                        isGood = false;
                    }
                }

            }
            else
            {//无优先边
                if (unpick > 0 && solid > 0)
                {
                    if ((unpick & 1) == (solid & 1))
                    {//非定链和固定链奇偶相同

                        isGood = false;
                    }
                    else
                    {//可以搜索改变优先边的条数，先简单的任意给出个固定链边,需要更新我方构成的完链
                        isGood = true;

                    }
                }
                else if (unpick > 0)
                {//非固定链非0，固定链为0
                   if((unpick & 1) == 1)
                   {
                       isGood = true;
                   }
                   else
                   {
                       isGood = false;
                   }
                }
                else if (solid > 0)
                {//非固定链0，固定链非0
                    if ((solid & 1) == 1)
                    {
                        isGood = true;
                    }
                    else
                    {
                        isGood = false;
                    }
                }
                else
                {
                    isGood = false;
                }
            }
            return isGood;
        }
        /// <summary>
        /// 获取一个完全格链的类型，0表示不是完链，1表示非定完链，2表示固定完链，3表示活动完链
        /// </summary>
        /// <param name="boxes">一组格链</param>
        /// <returns>格链类型</returns>
        int GetCompleteLinkType(List<int> boxes)
        {
            int link_type = 0;
            List<int> sides = LinkToSides(boxes);
            if(boxes.Count == 0)
            {
                link_type = 0;
            }
            else if(boxes.Count == 1 || sides.Count == 1)
            {//固定完链
                link_type = 2;
            }
            else if(boxes.Count == 2)
            {
                sides.Sort();
                if ((sides[1] - sides[0] == 1) || (box_asociate_sides_e[boxes[0]].Count == box_asociate_sides_e[boxes[1]].Count))
                    link_type = 2;
                else
                    link_type = 1;

            }
            else
            {
                //这个地方有问题
                if (sides.Count <= boxes.Count - 1 && (boxes.Count & 1) == 0 && boxes.Count > 4)//5.15日修改，如果完链格是偶数并且大于4，就占
                    link_type = 2;
                else
                    link_type = 3;
            }

            return link_type;
        }
        /// <summary>
        /// 获取格链的类型
        /// </summary>
        /// <param name="boxes">一个格链</param>
        /// <returns></returns>
        int GetLinkType(List<int> boxes)
        {
            int link_type = 0;
            List<int> sides = LinkToSides(boxes);
            if (boxes.Count == 1)
            {//固定链
                link_type = 2;
            }
            else if (boxes.Count == 2)
            {
                //sides.Sort();
                //if ((sides[1] - sides[0] == 1) || (sides[2]-sides[1] == 1))
                //    link_type = 1;
                //else
                //    link_type = 2;
                link_type = 1;

            }
            else
            {
                //这个地方有问题
                //if (boxes.Count == sides.Count+1)
                //    link_type = 2;
                //else
                    link_type = 3;
            }

            return link_type;
        }
        /// <summary>
        /// 将一个格链转化为连续可下边
        /// </summary>
        /// <param name="boxes">一个格链</param>
        /// <returns></returns>
        List<int> LinkToSides(List<int> boxes)
        {
            List<int> sides = new List<int>();
            foreach (int box in boxes)
            {
                sides.AddRange(box_asociate_sides_e[box]);
            }
            return sides.Distinct().ToList();
        }
        int GetSymSide(int side)
        {
            int sym_side = -1;
            if(v_single_sides.Contains(side))
            {
                int half = v_single_sides.Count / 2;
                int pos = v_single_sides.IndexOf(side);
                if(pos<half)
                {
                    int half_low = half / 2;
                    if(pos<half_low)
                        sym_side = v_single_sides[half_low + half_low - pos - 1];
                    else
                        sym_side = v_single_sides[half_low - (pos - half_low + 1)];
                }
                else
                {
                    int half_high = half + half / 2;
                    if (pos < half_high)
                        sym_side = v_single_sides[half_high + half_high - pos - 1];
                    else
                        sym_side = v_single_sides[half_high - (pos - half_high + 1)];
                }
            }
            else if(v_double_sides.Contains(side))
            {
                int half = v_double_sides.Count / 2;
                int pos = v_double_sides.IndexOf(side);
                if (pos < half)
                {
                    int half_low = half / 2;
                    if (pos < half_low)
                        sym_side = v_double_sides[half_low + half_low - pos - 1];
                    else
                        sym_side = v_double_sides[half_low - (pos - half_low + 1)];
                }
                else
                {
                    int half_high = half + half / 2;
                    if (pos < half_high)
                        sym_side = v_double_sides[half_high + half_high - pos - 1];
                    else
                        sym_side = v_double_sides[half_high - (pos - half_high + 1)];
                }
            }
            return sym_side;
        }
	
	    
    }
}
